package com.tsx.leetcode.hot100.easy;

/**
 * <a href="https://leetcode.cn/problems/merge-two-sorted-lists">合并两个有序链表</a>
 * 将两个升序链表合并为一个新的 升序 链表并返回。新链表是通过拼接给定的两个链表的所有节点组成的。
 */
public class Q21MergeTwoLists {
    public static void main(String[] args) {
        // 一次性生成测试用例
        ListNode l1 = new ListNode(1);
        ListNode l2 = new ListNode(2);
        ListNode l3 = new ListNode(4);
        l1.next = l2;
        l2.next = l3;
        l3.next = null;
        ListNode l4 = new ListNode(1);
        ListNode l5 = new ListNode(3);
        ListNode l6 = new ListNode(4);
        l4.next = l5;
        l5.next = l6;
        l6.next = null;
        ListNode head = mergeTwoLists(l1, l4);
        printLinkedList(head);
    }

    public static ListNode mergeTwoLists(ListNode list1, ListNode list2) {
        if (list1 == null && list2 == null) { // 要是都为空，则返回空
            return null;
        }
        ListNode p1 = list1; // 指向链表1
        ListNode p2 = list2; // 链表2
        ListNode head = new ListNode(); // 新链表头节点
        ListNode p = head; // 新链表当前节点
        while (p1 != null && p2 != null) { // 当两个链表都不为空时
            if (p1.val < p2.val) { // 比较两个链表当前节点的值
                p.next = p1; // 新链表当前节点的next指向链表1的当前节点
                p1 = p1.next; // 链表1的当前节点后移
            } else {
                p.next = p2; // 新链表当前节点的next指向链表2的当前节点
                p2 = p2.next; // 链表2的当前节点后移
            }
            p = p.next; // 新链表当前节点后移
        }
        p.next = p1 == null ? p2 : p1; // 链表1和链表2的长度可能不相等
        return head.next; // 新链表的头节点
    }

    public static class ListNode {
        int val;
        ListNode next;

        ListNode() {
        }

        ListNode(int val) {
            this.val = val;
        }

        ListNode(int val, ListNode next) {
            this.val = val;
            this.next = next;
        }
    }

    public static void printLinkedList(ListNode head) {
        ListNode p = head;
        while (p != null) {
            System.out.println(p.val);
            p = p.next;
        }
    }
}
